<!--
Copyright 2014 The Chromium Authors. All rights reserved.
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file.
-->

<link rel="import" href="../lib/dygraph.html">
<link rel="import" href="../lib/log.html">
<link rel="import" href="../model/patch-summary.html">
<link rel="import" href="../model/patch-summary-list.html">
<link rel="import" href="./tom-patch-summary-list.html">

<polymer-element name="tom-cq-graph" attributes="graph">
  <template>
    <style>
      ul, .loading {
        font-weight: bold;
      }
      tom-cq-graph-item {
        font-weight: normal;
      }
      #graphContainer {
        position: relative;
        height: 200px;
      }
      #graphDiv {
        position: absolute;
        left: 0;
        top: 0;
        right: 0;
        bottom: 0;
      }
    </style>
    <h2>{{ graph.heading }}</h2>
    <template if="{{ _hasAlerts() }}">
      Alert thresholds: {{ _alertText() }}
    </template>
    <div id="graphContainer"><div id="graphDiv"></div></div>
    <template if="{{ graph.data.rowItemsAvailable }}">
      <tom-patch-summary-list model="{{ _patchSummaryList }}"></tom-patch-summary-list>
    </template>
    <template if="{{ _loading }}">
      <span class="loading">Loading...</span>
    </template>
  </template>
  <script>
    (function() {
    Polymer({
      ready: function() {
        this._patchSummaryList = new PatchSummaryList(this.graph.itemUnit);
        this._loading = true;
        this._dygraph = null;
        var self = this;
        this.graph.data.get().then(function(data) {
          self._loading = false;
          self._drawGraph(data);
        }).catch(log);
        this.$.graphDiv.addEventListener('click',
            this._onGraphClick.bind(this));
      },
      _drawGraph: function(data) {
        this._dygraph = new Dygraph(this.$.graphDiv, data.rows, {
          labels: data.cols,
          legend: 'always',
          highlightSeriesOpts: {
            strokeWidth: 3,
            highlightCircleSize: 4,
          },
          highlightSeriesBackgroundAlpha: 1,
          hideOverlayOnMouseOut: false,
          ylabel: this.graph.unit,
          strokeWidth: 2,
          colors: ['purple', 'orange', 'lightblue', 'green', 'black'],
          underlayCallback: this._onGraphDrawUnderlay.bind(this),
        });
        // Overwrite default white legend background to be translucent.
        var legend = this.$.graphDiv.querySelector('.dygraph-legend');
        legend.style.backgroundColor = 'rgba(255, 255, 255, 0.8)';
      },
      _onGraphClick: function() {
        if (!this._dygraph || !this.graph.data.rowItemsAvailable) {
          return;
        }
        this._patchSummaryList.clear();
        var row = this._dygraph.getSelection();
        if (row !== -1) {
          this._loading = true;
          var self = this;
          this.graph.data.rowItems(row).then(function(rowItems) {
            self._loading = false;
            self._patchSummaryList.set(rowItems.begin, rowItems.end,
                rowItems.items.map(function(item) {
              var itemValue = item[0];
              var itemRef = item[1];
              return new PatchSummary(itemValue, self.graph.itemUnit,
                  itemRef.issue, itemRef.patchset,
                  self.graph.itemAlertThreshold);
            }));
          }).catch(log);
        }
      },
      _onGraphDrawUnderlay: function(context, area, dygraph) {
        var self = this;
        Object.keys(this.graph.alerts, function(col, threshold) {
          self.graph.breachedItems(col, threshold).then(function(items) {
            context.strokeStyle = 'red';
            context.lineWidth = 5;
            context.lineCap = 'round';
            context.beginPath();
            var radius = 6;
            items.forEach(function(item) {
              var x = dygraph.toDomXCoord(item.timestamp);
              var valueY = dygraph.toDomYCoord(item.value);
              var thresholdY = Math.max(
                  dygraph.toDomYCoord(threshold), valueY + radius);
              context.moveTo(x, thresholdY);
              context.lineTo(x, valueY + radius);
              context.arc(x, valueY, radius, Math.PI * 0.5, Math.PI * 2.5);
            });
            context.stroke();
          });
        });
      },
      _hasAlerts: function() {
        return Object.keys(this.graph.alerts).length > 0;
      },
      _alertText: function() {
        var items = [];
        var unit = this.graph.unit;
        Object.keys(this.graph.alerts, function(col, threshold) {
          items.push('{1} ≥ {2} {3}'.assign(col, threshold, unit));
        });
        return items.join(', ');
      },
    });
    })();
  </script>
</polymer-element>
